﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OCR.Algorithm;
using OCR.Config;
using OCR.SystemThread;

namespace OCR.SettingsForm
{
    public partial class AlgorithmForm : Form
    {
        public static bool isNullFiles;
        public AlgorithmForm()
        {
            InitializeComponent();
        }
        //mainCameraPb的初始位置
        private System.Drawing.Point PicStartPos;
        //mainCameraPb的初始大小
        private System.Drawing.Size PicSize;
        //鼠标滚轮缩放图片的增量值
        private int ZoomStep = 40;

        public bool isMainCameraPbWheel;
        private void mainCameraPb_MouseWheel(object sender, MouseEventArgs e)
        {
            if (pictureBox1.Image == null) return;
            //if (!isMainCameraPbWheel) return;

            PictureBox pbox = pictureBox1;
            int x = e.Location.X;
            int y = e.Location.Y;
            int ow = pbox.Width;
            int oh = pbox.Height;
            int VX, VY;  //因缩放产生的位移矢量
            if (e.Delta > 0) //放大
            {
                //第1步
                pbox.Width += ZoomStep;
                pbox.Height += ZoomStep;
                //第2步
                PropertyInfo pInfo = pbox.GetType().GetProperty("ImageRectangle", BindingFlags.Instance | BindingFlags.NonPublic);
                Rectangle rect = (Rectangle)pInfo.GetValue(pbox, null);
                //第3步
                pbox.Width = rect.Width;
                pbox.Height = rect.Height;

                //Console.WriteLine(string.Format("宽：{0}，高：{1}",pbox.Width,pbox.Height));
            }
            if (e.Delta < 0) //缩小
            {
                if (pbox.Width < 1200)
                {
                    ReturnManiCameraPb();
                    return;
                }
                //防止一直缩成负值
                //if (pbox.Width < 1100)
                //    return;

                pbox.Width -= ZoomStep;
                pbox.Height -= ZoomStep;
                PropertyInfo pInfo = pbox.GetType().GetProperty("ImageRectangle", BindingFlags.Instance |
                 BindingFlags.NonPublic);
                Rectangle rect = (Rectangle)pInfo.GetValue(pbox, null);
                pbox.Width = rect.Width;
                pbox.Height = rect.Height;
            }

            //第4步，求因缩放产生的位移，进行补偿，实现锚点缩放的效果
            VX = (int)((double)x * (ow - pbox.Width) / ow);
            VY = (int)((double)y * (oh - pbox.Height) / oh);
            pbox.Location = new System.Drawing.Point(pbox.Location.X + VX, pbox.Location.Y + VY);
        }
        public void ReturnManiCameraPb()
        {

            if (pictureBox1 != null && pictureBox1.Image != null)
            {
                pictureBox1.Image = pictureBox1.Image;
                //设置坐标
                pictureBox1.Location = PicStartPos;
                pictureBox1.Size = PicSize;
            }
        }
        private void AlgorithmForm_Load(object sender, EventArgs e)
        {

            //AlgorithmModule.CreateInstance();
            //AlgorithmModule.ImageHandleV2("TemplateInput\\Refresh.bmp");
            pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;

            PicStartPos = pictureBox1.Location;
            PicSize = pictureBox1.Size;
            this.pictureBox1.MouseWheel += new MouseEventHandler(this.mainCameraPb_MouseWheel);
        }

        private List<string> _imagePaths = new List<string>();
        private int _currentIndex = -1;
        private List<string> _imageNames = new List<string>();

        private List<FileInfo> _imageFiles = new List<FileInfo>();
        private List<FileInfo> _imageFiles_A = new List<FileInfo>();
        private List<FileInfo> _imageFiles_NO_A = new List<FileInfo>();
        private void LoadImagesFromFolder(string folderPath)
        {
            _imagePaths.Clear();
            _imageNames.Clear();
            _imageFiles.Clear();
            if (!Directory.Exists(folderPath)) return;

            DirectoryInfo dir = new DirectoryInfo(folderPath);
            FileInfo[] fileInfo = dir.GetFiles("*.*", SearchOption.AllDirectories);
            var extensions = new[] { ".jpg", ".jpeg", ".png", ".bmp", ".gif" };
            foreach (FileInfo file in fileInfo)
            {
                if (extensions.Contains(file.Extension.ToLower()))
                {
                    Console.WriteLine(file.Name);
                    _imageFiles.Add(file);
                }
            }
            _currentIndex = _imageFiles.Count > 0 ? 0 : -1;


            if (_imageFiles.Count == 0)
            {
                isNullFiles = true;
                MessageBox.Show("路径中无图片");
            }
            else
            {
                isNullFiles = false;
            }


            for (int i = 0; i < _imageFiles.Count; i++)
            {
                if (_imageFiles[i].Name.Split('_').Length >= 3)
                {
                    if (_imageFiles[i].Name.Split('_')[_imageFiles[i].Name.Split('_').Length - 2] == "A")
                    {
                        _imageFiles_A.Add(_imageFiles[i]);

                    }
                    else
                    {
                        _imageFiles_NO_A.Add(_imageFiles[i]);
                    }
                }
                else
                {
                    _imageFiles_NO_A.Add(_imageFiles[i]);
                }
            }
            Console.WriteLine("_imageFiles_NO_A.Count:   " + _imageFiles_NO_A.Count);

            foreach (var item in _imageFiles_NO_A)
            {
                Console.WriteLine("_imageFiles_NO_A: " + item);
            }

        }
        private void ShowCurrentImage()
        {
            if (isNullFiles) return;

            if (_currentIndex < 0 || _currentIndex >= _imageFiles_NO_A.Count) return;

            try
            {
                Console.WriteLine(_imageFiles_NO_A[_currentIndex]);
                //pictureBox1.Image?.Dispose(); // 释放上一张图片资源
                ImgNameTB.Text = _imageFiles_NO_A[_currentIndex].Name;

                if (isTemcb.Checked)
                {
                    Template_SelectImg(_imageFiles_NO_A[_currentIndex].FullName);
                }
                else
                {
                    Image temp = Image.FromFile(_imageFiles_NO_A[_currentIndex].FullName);
                    //AlgorithmModule_GPU.ImageHandleV2_ByteArray(_imagePaths[_currentIndex]);
                    AlgorithmModule_GPU.ImageHandleV2_Opencv(_imageFiles_NO_A[_currentIndex].FullName);
                    temp.Dispose();
                    Bitmap bitmap1 = (Bitmap)AlgorithmModule_GPU.RectPoints((Bitmap)Image.FromFile(_imageFiles_NO_A[_currentIndex].FullName), AlgorithmModule_GPU.pointsList);
                    pictureBox1.Image = (Bitmap)AlgorithmModule_GPU.RectPoints1(bitmap1, AlgorithmModule_GPU.pointsList, AlgorithmModule_GPU.currConfigs);
                }

                infoTB01.Text = infoTB02.Text = infoTB03.Text = infoTB04.Text = infoTB05.Text = infoTB06.Text = string.Empty;
                if (AlgorithmModule_GPU.currConfigs.Count >= 1)
                    infoTB01.Text = AlgorithmModule_GPU.currConfigs[0].text;
                if (AlgorithmModule_GPU.currConfigs.Count >= 2)
                    infoTB02.Text = AlgorithmModule_GPU.currConfigs[1].text;
                if (AlgorithmModule_GPU.currConfigs.Count >= 3)
                    infoTB03.Text = AlgorithmModule_GPU.currConfigs[2].text;
                if (AlgorithmModule_GPU.currConfigs.Count >= 4)
                    infoTB04.Text = AlgorithmModule_GPU.currConfigs[3].text;
                if (AlgorithmModule_GPU.currConfigs.Count >= 5)
                    infoTB05.Text = AlgorithmModule_GPU.currConfigs[4].text;
                if (AlgorithmModule_GPU.currConfigs.Count >= 6)
                    infoTB06.Text = AlgorithmModule_GPU.currConfigs[5].text;
            }
            catch (Exception ex)
            {
                MessageBox.Show($"图片加载失败: {ex.Message}");
            }


        }

        private void PrevBtn_Click(object sender, EventArgs e)
        {
            if (_imageFiles_NO_A.Count == 0) return;

            _currentIndex = (_currentIndex > 0) ? _currentIndex - 1 : _imageFiles_NO_A.Count - 1;
            ShowCurrentImage();
        }

        private void NextBtn_Click(object sender, EventArgs e)
        {
            if (_imageFiles_NO_A.Count == 0) return;

            _currentIndex = (_currentIndex + 1) % _imageFiles_NO_A.Count;
            ShowCurrentImage();
        }

        // 选择文件夹按钮
        private void SelectImgFolder()
        {
            using (var dialog = new FolderBrowserDialog())
            {
                dialog.SelectedPath = Application.StartupPath;
                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    LoadImagesFromFolder(dialog.SelectedPath);
                    ShowCurrentImage();
                    //for (int i = 0; i < _imagePaths.Count; i++)
                    //{
                    //    _currentIndex = i;
                    //    ShowCurrentImage();
                    //}
                }
            }
        }

        private void SelectImgFolderBtn_Click(object sender, EventArgs e)
        {
            SelectImgFolder();
        }

        Bitmap bitmap;
        private void SelectImgBtn_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                openFileDialog.Filter = "图片文件|*.jpg;*.jpeg;*.png;*.bmp;*.gif";
                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        FileInfo fileInfo = new FileInfo(openFileDialog.FileName);
                        Console.WriteLine("openFileDialog.FileName: " + openFileDialog.FileName + "    fileInfo: " + fileInfo.Name);
                        ImgNameTB.Text = fileInfo.Name;

                        if (isTemcb.Checked)
                        {
                            Template_SelectImg(openFileDialog.FileName);
                        }
                        else
                        {
                            Bitmap FileBitmap = (Bitmap)Image.FromFile(openFileDialog.FileName);
                            //AlgorithmModule_GPU.ImageHandleV2_ByteArray(FileBitmap);
                            AlgorithmModule_GPU.ImageHandleV2_Opencv(FileBitmap);

                            bitmap = (Bitmap)AlgorithmModule_GPU.RectPoints((Bitmap)Image.FromFile(openFileDialog.FileName), AlgorithmModule_GPU.pointsList);

                            bitmap = (Bitmap)AlgorithmModule_GPU.RectPoints1(bitmap, AlgorithmModule_GPU.pointsList, AlgorithmModule_GPU.currConfigs);

                            pictureBox1.Image = bitmap;
                        }


                        foreach (var item in AlgorithmModule_GPU.currConfigs)
                        {
                            Console.WriteLine(item.text);
                        }
                        infoTB01.Text = infoTB02.Text = infoTB03.Text = infoTB04.Text = infoTB05.Text = infoTB06.Text = string.Empty;
                        if (AlgorithmModule_GPU.currConfigs.Count >= 1)
                            infoTB01.Text = AlgorithmModule_GPU.currConfigs[0].text;
                        if (AlgorithmModule_GPU.currConfigs.Count >= 2)
                            infoTB02.Text = AlgorithmModule_GPU.currConfigs[1].text;
                        if (AlgorithmModule_GPU.currConfigs.Count >= 3)
                            infoTB03.Text = AlgorithmModule_GPU.currConfigs[2].text;
                        if (AlgorithmModule_GPU.currConfigs.Count >= 4)
                            infoTB04.Text = AlgorithmModule_GPU.currConfigs[3].text;
                        if (AlgorithmModule_GPU.currConfigs.Count >= 5)
                            infoTB05.Text = AlgorithmModule_GPU.currConfigs[4].text;
                        if (AlgorithmModule_GPU.currConfigs.Count >= 6)
                            infoTB06.Text = AlgorithmModule_GPU.currConfigs[5].text;
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show($"无法打开文件: {ex.Message}");

                    }
                }
            }


        }

        private void AlgorithmForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (bitmap != null)
                bitmap.Dispose();

            OCR_Form.oCR_Form.algorithmForm = null;
        }

        public FinalInfoData finalInfoData;
        public void Template_SelectImg(string path)
        {
            ReturnManiCameraPb();
            finalInfoData = new FinalInfoData();
            Bitmap finalBit = (Bitmap)Image.FromFile(path);

            //裁剪拼接
            List<Rectangle> roiLocations = new List<Rectangle>();
            finalBit = OCR_Form.StitchROIs_Middle(finalBit, LocalTemplateSingleInfos_Config.rectangles, out roiLocations);

            //string currTime = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-fffffff");
            //finalBit.Save(Application.StartupPath + "\\test\\" + currTime + "_NG_A_" + Guid.NewGuid().ToString("N") + "_combine" + ".jpeg", System.Drawing.Imaging.ImageFormat.Jpeg);


            //AlgorithmModule_GPU.ImageHandleV2_ByteArray(finalBit);
            AlgorithmModule_GPU.ImageHandleV2_Opencv(finalBit);

            //映射回原图
            List<Rectangle> convertRectangles = OCR_Form.MapBackToOriginal(OCR_Form.ConvertToRectangles(AlgorithmModule_GPU.pointsList), roiLocations, LocalTemplateSingleInfos_Config.rectangles);
            AlgorithmModule_GPU.pointsList = OCR_Form.ConvertToPointLists(convertRectangles);

            //AlgorithmModule_GPU.ImageHandleV2_ByteArray(finalBit);


            //bool isSame = LocalTemplateInfo.CompareTemplate(AlgorithmModule_GPU.mainInfos);

            LocalTemplateSingleInfos_Config.finalPointsList.Clear();
            LocalTemplateSingleInfos_Config.mainInfos.Clear();
            LocalTemplateSingleInfos_Config.temInfos.Clear();

            //储存多个模板所有信息 --temInfos
            for (int i = 0; i < LocalTemplateSingleInfos_Config.localTemplateSingleInfos.Count; i++)
            {
                for (int j = 0; j < LocalTemplateSingleInfos_Config.localTemplateSingleInfos[i].InfoList.Count; j++)
                {
                    LocalTemplateSingleInfos_Config.temInfos.Add(LocalTemplateSingleInfos_Config.localTemplateSingleInfos[i].InfoList[j]);
                    //Console.WriteLine("temInfos.Count:" + LocalTemplateSingleInfos_Config.temInfos.Count);
                }

            }

            List<bool> isSameList = new List<bool>();
            //传入外框-rectangles，设置多个模板的信息-infosList，是否框内-insideList，点位-finalPointsLists
            for (int i = 0; i < LocalTemplateSingleInfos_Config.localTemplateSingleInfos.Count; i++)
            {
                //LocalTemplateSingleInfos_Config.Compare(LocalTemplateSingleInfos_Config.rectangles[i], LocalTemplateSingleInfos_Config.infosList[i], LocalTemplateSingleInfos_Config.insideList[i], LocalTemplateSingleInfos_Config.finalPointsLists[i]);
                LocalTemplateSingleInfos_Config.CompareConfuse(LocalTemplateSingleInfos_Config.rectangles[i], LocalTemplateSingleInfos_Config.infosList[i], LocalTemplateSingleInfos_Config.insideList[i], LocalTemplateSingleInfos_Config.finalPointsLists[i], LocalTemplateSingleInfos_Config.confuseMultiIndex[i], LocalTemplateSingleInfos_Config.confuseMultiIndexDic[i]);

            }
            //无序对比单个模板内的信息
            for (int i = 0; i < LocalTemplateSingleInfos_Config.localTemplateSingleInfos.Count; i++)
            {
                isSameList.Add(LocalTemplateSingleInfos_Config.CompareTemplate_Disorder(LocalTemplateSingleInfos_Config.localTemplateSingleInfos[i].InfoList, LocalTemplateSingleInfos_Config.infosList[i]));
            }
            Console.WriteLine("isSameList.Count:" + isSameList.Count);
            Console.WriteLine("isSameList:" + isSameList.All(x => x));
            bool isSame = isSameList.All(x => x);

            for (int i = 0; i < LocalTemplateSingleInfos_Config.localTemplateSingleInfos.Count; i++)
            {
                //LocalTemplateSingleInfos_Config.CompareTemplate_Disorder_SingleRectInfo(LocalTemplateSingleInfos_Config.infosList[i],LocalTemplateSingleInfos_Config.localTemplateSingleInfos[i].InfoList);
            }

            //LocalTemplateSingleInfos_Config.CompareTemplate_Disorder_AllInfo(LocalTemplateSingleInfos_Config.temInfos, LocalTemplateSingleInfos_Config.mainInfos);

            //bool isSame = LocalTemplateInfo.CompareTemplate_Disorder(AlgorithmModule_GPU.mainInfos);
            //Console.WriteLine(isSame);
            if (!isSame)
            {
                Console.WriteLine("GPU-NG");

                //Console.WriteLine("isSameList--:" + isSameList.ToArray().Count(b => b == false));

                //Console.WriteLine("isSameList--:" + Array.FindAll(isSameList.ToArray(), b => !b).Length);

                //FinalInfoData finalInfoData = new FinalInfoData();
                //finalInfoData.Bitmap = (Bitmap)finalBit.Clone();
                finalInfoData.Bitmap = new Bitmap(Image.FromFile(path));
                finalInfoData.result = "NG";
                finalInfoData.wrongIndex = LocalInfo.wrongIndex;
                finalInfoData.wrongString = LocalInfo.wrongString;
                finalInfoData.isSame = isSameList;
                //infoQueue.Enqueue(finalInfoData);

            }
            else
            {
                Console.WriteLine("GPU-OK");
                //FinalInfoData finalInfoData = new FinalInfoData();
                //finalInfoData.Bitmap= (Bitmap)CameraReceiveThread.frameForSave.Image.ToBitmap().Clone();
                finalInfoData.Bitmap = new Bitmap(Image.FromFile(path));
                finalInfoData.result = "OK";
                finalInfoData.wrongIndex = LocalInfo.wrongIndex;
                finalInfoData.wrongString = LocalInfo.wrongString;
                finalInfoData.isSame = isSameList;
                //infoQueue.Enqueue(finalInfoData);

            }

            Image tempImg = AlgorithmModule_GPU.RectPoints(
    (Bitmap)AlgorithmModule_GPU.RectPoints1(finalInfoData.Bitmap, LocalTemplateSingleInfos_Config.finalPointsList, finalInfoData.wrongIndex, LocalTemplateSingleInfos_Config.mainInfos, finalInfoData.wrongString)
    , LocalTemplateSingleInfos_Config.rectangles, finalInfoData.isSame);
            pictureBox1.Image = LocalTemplateSingleInfos_Config.RectDrawString((Bitmap)tempImg, finalInfoData.isSame);
        }


        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                ReturnManiCameraPb();
            }
        }
    }
}
